package com.mangix.http;

import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.util.BytesContentProvider;
import org.eclipse.jetty.client.util.PathContentProvider;
import org.json.simple.JSONValue;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.nio.file.FileStore;
import java.nio.file.Path;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;

/**
 * Created by Ahan on 2014/7/21.
 */
public class MangixHttpClient {

    private static HttpClient httpClient = null;

    public static synchronized HttpClient getHttpClient() {
        if (httpClient == null) {
            httpClient = new HttpClient();
            try {
                httpClient.start();
            } catch (Exception e) {
                e.printStackTrace();
                System.exit(-1);
            }
        }
        return httpClient;
    }

    /**
     * Get meta
     * @param url
     * @return
     * @throws IOException
     */
    public static String head(String url, String headerFiled) throws IOException {
        HttpURLConnection conn = null;
        try {
            URL http = new URL(url);
            conn = (HttpURLConnection) http.openConnection();
            conn.setRequestMethod("HEAD");

            int status = conn.getResponseCode();
            if (status == 200) {
                return conn.getHeaderField(headerFiled);
            } else {
                throw new IOException(conn.getResponseMessage());
            }
        } finally {
//            if (in != null) {
//                in.close();
//            }
            if (conn != null) {
                conn.disconnect();
            }
        }
    }

    /**
     *
     * @param url
     * @return
     * @throws IOException
     */
    public static String get(String url) throws IOException {
        HttpURLConnection conn = null;
        BufferedReader in = null;
        try {
            URL http = new URL(url);
            conn = (HttpURLConnection) http.openConnection();
//            conn.setRequestProperty("Connection", "close");
            in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuffer content = new StringBuffer();
            String line;
            while((line = in.readLine()) != null) {
                content.append(line);
            }
            int status = conn.getResponseCode();
            if (status == 200) {
                return content.toString();
            } else {
                throw new IOException(content.toString());
            }
        } finally {
            if (in != null) {
                in.close();
            }
            if (conn != null) {
                conn.disconnect();
            }
        }
    }

    public static void put(String url, String content) throws IOException {
        HttpURLConnection conn = null;
        OutputStreamWriter out = null;
        try {
            URL http = new URL(url);
            conn = (HttpURLConnection) http.openConnection();
            conn.setRequestMethod("PUT");
//            conn.setRequestProperty("Connection", "close");
            conn.setDoOutput(true);
            out = new OutputStreamWriter(
                    conn.getOutputStream());
            out.write(content);
            out.flush();
            // Send the content.
            conn.getInputStream().close();
            if (conn.getResponseCode() != 200) {
                throw new IOException("Put url: " + url + ", content: " + content);
            }
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            conn.disconnect();
        }
    }

    public static void put(String url, Path file, String version, int replicasNum) throws Exception {
        HttpURLConnection conn = null;
        OutputStream out = null;
        FileInputStream inputStream = null;
        try {
            URL http = new URL(url);
            conn = (HttpURLConnection) http.openConnection();
            conn.setRequestMethod("PUT");
            conn.setRequestProperty(MangixHttpHeader.VERSION, version);
            conn.setRequestProperty(MangixHttpHeader.REPLICAS_NUM, replicasNum + "");
            conn.setDoOutput(true);
            conn.setFixedLengthStreamingMode(file.toFile().length());
            out = conn.getOutputStream();
            byte[] buffer = new byte[1024];
            int len = -1;
            System.out.println("Begin to put: " + url + " file: " + file.toString());
            inputStream = new FileInputStream(file.toFile());
            while((len = inputStream.read(buffer)) != -1) {
                out.write(buffer, 0, len);
            }
            out.close();
            System.out.println("Finish put: " + url + " file: " + file.toString());
            // Send the content.
            if (conn.getResponseCode() != 200) {
                throw new IOException("Put url: " + url + ", file: " + file.toString() + " failed. Error code: " + conn.getResponseCode() + " Error message: " + conn.getResponseMessage());
            }
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    //e.printStackTrace();
                }
            }
            if (inputStream != null) {
                inputStream.close();
            }
            conn.disconnect();
        }
    }

    public static void delete(String url) throws IOException {
        HttpURLConnection conn = null;
        BufferedReader in = null;
        try {
            URL http = new URL(url);
            conn = (HttpURLConnection) http.openConnection();
            conn.setRequestMethod("DELETE");
            int status = conn.getResponseCode();
            if (status != 200) {
                throw new IOException(conn.getResponseMessage());
            }
        } finally {
            if (in != null) {
                in.close();
            }
            if (conn != null) {
                conn.disconnect();
            }
        }
    }

    public static void delete(String url, String version) throws IOException {
        HttpURLConnection conn = null;
        BufferedReader in = null;
        try {
            URL http = new URL(url);
            conn = (HttpURLConnection) http.openConnection();
            conn.setRequestMethod("DELETE");
            conn.setRequestProperty(MangixHttpHeader.VERSION, version);
            int status = conn.getResponseCode();
            if (status != 200) {
                throw new IOException(conn.getResponseMessage());
            }
        } finally {
            if (in != null) {
                in.close();
            }
            if (conn != null) {
                conn.disconnect();
            }
        }
    }
}
